package com.czkevin.cif.crafting.gui;

import com.czkevin.cif.CustomItemFramework;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.entity.HumanEntity;
import org.bukkit.event.inventory.InventoryClickEvent;
import org.bukkit.inventory.ItemStack;
import com.czkevin.guicontrolsapi.controls.GUIControl;

import java.util.function.BiConsumer;

public class CraftingMatrixControl extends GUIControl {

    private final int width, height;
    private BiConsumer<HumanEntity, ItemStack[][]> callback;

    private ItemStack[][] matrix;

    private boolean disabled = false;

    public CraftingMatrixControl(int width, int height) {
        this(width, height, null);
    }

    public CraftingMatrixControl(int width, int height, BiConsumer<HumanEntity, ItemStack[][]> callback) {
        if(width < 1 || height < 1) throw new IllegalArgumentException("Invalid matrix dimension! ");
        this.width = width;
        this.height = height;
        this.callback = callback;
        matrix = new ItemStack[height][];
        for(int y = 0; y < height; y++) matrix[y] = new ItemStack[width];
    }

    public void setCallback(BiConsumer<HumanEntity, ItemStack[][]> callback) {
        this.callback = callback;
    }

    @Override
    public void onClick(InventoryClickEvent inventoryClickEvent, int localX, int localY) {
        // if(inventoryClickEvent.getAction() == InventoryAction.COLLECT_TO_CURSOR || inventoryClickEvent.getAction() == InventoryAction.UNKNOWN || inventoryClickEvent.getAction() == InventoryAction.MOVE_TO_OTHER_INVENTORY) {
        if (!inventoryClickEvent.getAction().name().startsWith("PICKUP_") && !inventoryClickEvent.getAction().name().startsWith("PLACE_")) {
            // IMPORTANT FIX TO ITEM DUPLICATION!!!
            return;
        }
        if(disabled) {
            return;
        }
        inventoryClickEvent.setCancelled(false);
        Bukkit.getScheduler().runTaskLater(CustomItemFramework.getInstance(), () -> {
            ItemStack stack = inventoryClickEvent.getClickedInventory().getItem(inventoryClickEvent.getSlot());
            if(stack != null && stack.getType() != Material.AIR) {
                stack = stack.clone();
            } else {
                stack = null;
            }
            CustomItemFramework.debug("Updated slot: " + (stack == null ? "null" : stack.toString()));
            matrix[localY][localX] = stack;
            callback.accept(inventoryClickEvent.getWhoClicked(), matrix);
        }, 1L);
    }

    public ItemStack[][] getMatrix() {
        return matrix;
    }

    public void applyMatrixToDisplay() {
        final int dx = getX();
        final int dy = getY();
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                getWindow().setDisplayItemAt(dx + x, dy + y, matrix[y][x]);
            }
        }
    }

    @Override
    public int getWidth() {
        return width;
    }

    @Override
    public int getHeight() {
        return height;
    }

    @Override
    public void onRender(boolean b) {
        applyMatrixToDisplay();
    }

    public void dropAll(Location location) {
        final World world = location.getWorld();
        final int dx = getX();
        final int dy = getY();
        for(int y = 0; y < height; y++) {
            for(int x = 0; x < width; x++) {
                if(matrix[y][x] != null && matrix[y][x].getType() != Material.AIR) world.dropItem(location, matrix[y][x]);
                getWindow().setDisplayItemAt(dx + x, dy + y, null);
            }
        }
    }

    public void setDisabled(boolean disabled) {
        this.disabled = disabled;
    }

    public boolean isDisabled() {
        return disabled;
    }
}
